package psn.hui.stat.utils;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.EnumMap;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 生成二维码
 * 
 * @author hui
 *
 */
public class ZXingCodeEncodeUtils {

	// 二维码颜色
	private static final int BLACK = 0xFF000000;
	// 二维码背景颜色
	private static final int WHITE = 0xFFFFFFFF;

	// 二维码格式参数
	private static final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(
			EncodeHintType.class);

	static {
		/**
		 * 二维码的纠错级别(拍错率)，4个级别：L(7%),M(15%),Q(25%),H(30%)
		 * 就错信息同样存储在二维码中，纠错级别越高，纠错信息占用的空间就越多，那么存储的有用信息就越少
		 */
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 二维码边界空白大小，1,2,3,4（4为默认，最大）
		hints.put(EncodeHintType.MARGIN, 1);
		// 设置内容的编码
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
	}

	/**
	 * 生成二维码保存到本地文件
	 * 
	 * @param content   二维码的内容
	 * @param width     二维码的宽度
	 * @param height    二维码的高度
	 * @param savePath  保存路径
	 * @param imageType 保存的图片类型
	 */
	public static void createZXingCodeSaveToDisk(String content, int width, int height, String savePath,
			String imageType) {
		try {
			BufferedImage codeimg = createZXingCode(content, width, height);
			// 保存图片
			File file = new File(savePath);
			if (!file.exists()) {
				file.createNewFile();
			}
			ImageIO.write(codeimg, imageType, file);
			System.out.println("生成成功");

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("生成失败");
	}

	/**
	 * 生成二维码图片并返回
	 * 
	 * @param content 二维码的内容
	 * @param width   二维码的宽度
	 * @param height  二维码的高度
	 */
	public static BufferedImage createZXingCode(String content, int width, int height) {
		try {
			// 生成二维矩阵信息
			BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
			int code_width = encode.getWidth();
			int code_height = encode.getHeight();
			// 创建图片
			BufferedImage img = new BufferedImage(code_width, code_height, BufferedImage.TYPE_INT_RGB);
			Graphics g = img.getGraphics();
			g.setColor(new Color(BLACK));
			// 将二维矩阵信息写入图片
			for (int x = 0; x < width; x++) {
				for (int y = 0; y < height; y++) {
					img.setRGB(x, y, encode.get(x, y) ? BLACK : WHITE);
				}
			}
			// 保存图片
			return img;

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("生成失败");
		return null;
	}

	/**
	 * 生成一张带logo的二维码保存到本地文件
	 * 
	 * @param content    二维码的内容
	 * @param width      二维码的宽度
	 * @param height     二维码的高度
	 * @param savePath   保存路径
	 * @param imageType  保存的图片类型
	 * @param logoStream logo的流对象
	 */
	public static void createZXingCodeUseLogoSaveToDisk(String content, int width, int height, String savePath,
			String imageType, InputStream logoStream) {
		try {
			BufferedImage codeimg = createZXingCodeUseLogo(content, width, height, logoStream);
			if (null == codeimg) {
				return;
			}
			// 保存图片
			File file = new File(savePath);
			if (!file.exists()) {
				file.createNewFile();
			}
			ImageIO.write(codeimg, imageType, file);
			System.out.println("生成成功");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成一张带logo的二维码图片
	 * 
	 * @param content    二维码的内容
	 * @param width      二维码的宽度
	 * @param height     二维码的高度
	 * @param logoStream logo的流对象
	 */
	public static BufferedImage createZXingCodeUseLogo(String content, int width, int height, InputStream logoStream) {
		try {
			// 生成二维码图片
			BufferedImage codeimg = createZXingCode(content, width, height);
			if (null == codeimg) {
				System.out.println("生成失败");
				return null;
			}
			if (null == logoStream) {
				System.out.println("logo流出错");
				return null;
			}
			BufferedImage logoimg = ImageIO.read(logoStream);
			// 拿到画笔
			Graphics g = codeimg.getGraphics();
			// 二维码的宽高
			int code_width = codeimg.getWidth();
			int code_height = codeimg.getHeight();
			// logo的最大宽高
			int logo_width_max = (int) (code_width * 0.15);
			int logo_height_max = (int) (code_height * 0.15);
			// logo的宽高
			int logo_width = Math.min(logo_width_max, logoimg.getWidth());
			int logo_height = Math.min(logo_height_max, logoimg.getHeight());
			// logo开始画的坐标（左上角）
			int start_x = (code_width - logo_width) / 2;
			int start_y = (code_height - logo_height) / 2;
			g.drawImage(logoimg, start_x, start_y, logo_width, logo_height, null);
			// 返回图片
			return codeimg;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
